<?php
// 音乐文件上传处理接口
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');

// 日志记录函数
function logMessage($message) {
    $logFile = __DIR__ . '/upload-music.log';
    $timestamp = date('Y-m-d H:i:s');
    $formattedMessage = "[{$timestamp}] {$message}\n";
    @file_put_contents($logFile, $formattedMessage, FILE_APPEND | LOCK_EX);
}

// 生成随机字符串
function generateRandomString($length = 8) {
    // 使用多种方法生成随机字符串，确保兼容性
    $randomString = '';
    
    // 尝试使用random_int
    if (function_exists('random_int')) {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        for ($i = 0; $i < $length; $i++) {
            try {
                $randomString .= $characters[random_int(0, $charactersLength - 1)];
            } catch (Exception $e) {
                // 如果random_int失败，使用备选方案
                break;
            }
        }
    }
    
    // 如果random_int不可用或失败，使用其他方法
    if (strlen($randomString) != $length) {
        $randomString = '';
        if (function_exists('openssl_random_pseudo_bytes')) {
            // 使用openssl生成随机字符串
            $randomString = substr(bin2hex(openssl_random_pseudo_bytes($length)), 0, $length);
        } else {
            // 使用mt_rand作为最后的备选方案
            $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            $charactersLength = strlen($characters);
            for ($i = 0; $i < $length; $i++) {
                $randomString .= $characters[mt_rand(0, $charactersLength - 1)];
            }
        }
    }
    
    return $randomString;
}

try {
    // 记录请求开始
    logMessage("Upload request received");
    
    // 检查是否是POST请求
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        logMessage("Invalid request method: " . $_SERVER['REQUEST_METHOD']);
        throw new Exception('只允许POST请求');
    }
    
    // 检查是否有文件上传数据
    if (!isset($_FILES['file']) || !isset($_FILES['file']['error'])) {
        logMessage("No file data in request");
        throw new Exception('没有文件被上传');
    }
    
    // 检查文件上传是否有错误
    switch ($_FILES['file']['error']) {
        case UPLOAD_ERR_OK:
            break;
        case UPLOAD_ERR_INI_SIZE:
        case UPLOAD_ERR_FORM_SIZE:
            logMessage("File size exceeds limit");
            throw new Exception('文件大小超过限制');
        case UPLOAD_ERR_PARTIAL:
            logMessage("File upload incomplete");
            throw new Exception('文件上传不完整');
        case UPLOAD_ERR_NO_FILE:
            logMessage("No file uploaded");
            throw new Exception('没有文件被上传');
        case UPLOAD_ERR_NO_TMP_DIR:
            logMessage("Missing temporary folder");
            throw new Exception('临时文件夹缺失');
        case UPLOAD_ERR_CANT_WRITE:
            logMessage("Failed to write file to disk");
            throw new Exception('文件写入失败');
        case UPLOAD_ERR_EXTENSION:
            logMessage("File upload stopped by extension");
            throw new Exception('文件上传被扩展限制');
        default:
            logMessage("Unknown upload error: " . $_FILES['file']['error']);
            throw new Exception('未知的文件上传错误');
    }
    
    // 获取文件信息
    $file = $_FILES['file'];
    
    // 验证文件基本信息
    if (!is_uploaded_file($file['tmp_name'])) {
        logMessage("Not an uploaded file: {$file['tmp_name']}");
        throw new Exception('非法文件上传');
    }
    
    logMessage("File info - name: {$file['name']}, size: {$file['size']}, tmp_name: {$file['tmp_name']}");
    
    // 检查文件大小 (限制为50MB)
    if ($file['size'] > 50 * 1024 * 1024) {
        logMessage("File too large: {$file['size']}");
        throw new Exception('文件大小不能超过50MB');
    }
    
    if ($file['size'] == 0) {
        logMessage("File is empty");
        throw new Exception('文件不能为空');
    }
    
    // 获取文件扩展名和原始名称
    $originalName = pathinfo($file['name'], PATHINFO_FILENAME);
    $fileExt = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    
    // 检查允许的音频文件类型
    $allowedExts = ['mp3', 'wav', 'ogg', 'aac', 'flac', 'm4a', 'wma'];
    if (!in_array($fileExt, $allowedExts)) {
        logMessage("Invalid file extension: {$fileExt}");
        throw new Exception('不支持的音频格式，仅支持: ' . implode(', ', $allowedExts));
    }
    
    // 验证MIME类型（仅在函数可用时）
    // 先检查finfo_open函数是否存在
    if (function_exists('finfo_open')) {
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        if ($finfo) {
            $mimeType = finfo_file($finfo, $file['tmp_name']);
            finfo_close($finfo);
            
            $allowedMimeTypes = [
                'audio/mpeg',      // mp3
                'audio/wav',       // wav
                'audio/ogg',       // ogg
                'audio/aac',       // aac
                'audio/flac',      // flac
                'audio/mp4',       // m4a
                'audio/x-ms-wma'   // wma
            ];
            
            if (!in_array($mimeType, $allowedMimeTypes)) {
                logMessage("Invalid MIME type: {$mimeType}");
                throw new Exception('文件类型验证失败');
            }
        }
    } else {
        logMessage("finfo_open function not available, skipping MIME type check");
    }
    
    // 生成唯一文件名（时间戳+随机字符串）
    $timestamp = time();
    $randomString = generateRandomString(12);
    $fileName = $timestamp . '_' . $randomString . '.' . $fileExt;
    
    logMessage("Generated fileName: {$fileName}");
    
    // 定义上传目录（使用绝对路径以增强兼容性）
    $basePath = '..';
    $uploadDir = rtrim($basePath . '/mp3', '/') . '/';
    
    logMessage("=== UPLOAD PATH INFORMATION ===");
    logMessage("Base path (relative to PHP file): {$basePath}");
    logMessage("Upload directory: {$uploadDir}");
    logMessage("Full upload directory path: " . realpath($uploadDir));
    logMessage("=== END UPLOAD PATH INFORMATION ===");
    
    // 检查基础路径是否存在
    if (!is_dir($basePath)) {
        logMessage("Base path does not exist: {$basePath}");
        throw new Exception('基础路径不存在');
    }
    
    // 检查上传目录是否存在，不存在则创建
    logMessage("Checking if upload directory exists: " . (is_dir($uploadDir) ? 'yes' : 'no'));
    if (!is_dir($uploadDir)) {
        logMessage("Upload directory does not exist, creating: {$uploadDir}");
        // 使用更兼容的方式创建目录
        if (!@mkdir($uploadDir, 0755, true)) {
            $error = error_get_last();
            logMessage("Failed to create upload directory with 0755: " . ($error ? $error['message'] : 'unknown error'));
            // 尝试使用0777权限创建
            if (!@mkdir($uploadDir, 0777, true)) {
                $error = error_get_last();
                logMessage("Failed to create upload directory with 0777: " . ($error ? $error['message'] : 'unknown error'));
                throw new Exception('无法创建上传目录');
            }
            logMessage("Upload directory created successfully with 0777");
        } else {
            logMessage("Upload directory created successfully with 0755");
        }
    }
    
    // 检查上传目录是否可写
    logMessage("Checking if upload directory is writable: " . (is_writable($uploadDir) ? 'yes' : 'no'));
    if (!is_writable($uploadDir)) {
        logMessage("Upload directory is not writable: {$uploadDir}");
        // 尝试修改权限
        if (!@chmod($uploadDir, 0755)) {
            logMessage("Failed to change permissions to 0755");
            // 尝试使用更宽松的权限
            if (!@chmod($uploadDir, 0777)) {
                logMessage("Failed to change permissions to 0777");
            } else {
                logMessage("Permissions changed to 0777");
            }
        } else {
            logMessage("Permissions changed to 0755");
        }
        // 再次检查
        if (!is_writable($uploadDir)) {
            logMessage("Upload directory is still not writable after chmod attempt");
            throw new Exception('上传目录不可写');
        }
        logMessage("Upload directory is now writable");
    }
    
    logMessage("Upload directory is writable");
    
    // 构造完整文件路径
    $filePath = $uploadDir . $fileName;
    logMessage("Target file path: {$filePath}");
    
    // 检查文件是否已存在（理论上不会，因为有随机字符串）
    if (file_exists($filePath)) {
        logMessage("File already exists: {$filePath}");
        throw new Exception('文件已存在');
    }
    
    // 记录文件路径
    logMessage("Target file path: {$filePath}");
    
    // 移动上传的文件
    logMessage("Moving uploaded file from {$file['tmp_name']} to {$filePath}");
    if (!move_uploaded_file($file['tmp_name'], $filePath)) {
        $error = error_get_last();
        logMessage("Failed to move uploaded file from {$file['tmp_name']} to {$filePath}: " . ($error ? $error['message'] : 'unknown error'));
        throw new Exception('文件保存失败');
    }
    
    // 检查文件是否成功保存
    if (!file_exists($filePath)) {
        logMessage("File not found after move: {$filePath}");
        throw new Exception('文件保存失败');
    }
    
    // 验证保存后的文件大小
    $savedFileSize = filesize($filePath);
    if ($savedFileSize !== $file['size']) {
        logMessage("File size mismatch: expected {$file['size']}, got " . $savedFileSize);
        @unlink($filePath); // 删除不匹配的文件
        throw new Exception('文件保存不完整');
    }
    
    // 设置文件权限
    @chmod($filePath, 0644);
    logMessage("File permissions set to 0644");
    
    // 构造可访问的URL
    $baseUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://') . 
               $_SERVER['HTTP_HOST'];
    $fileUrl = '/mp3/' . $fileName;
    
    logMessage("Upload successful, URL: {$fileUrl}");
    
    // 返回成功响应
    echo json_encode([
        'success' => true,
        'url' => $fileUrl,
        'full_url' => $baseUrl . $fileUrl,
        'filename' => $fileName,
        'original_name' => $file['name'],
        'size' => $file['size'],
        'message' => '上传成功'
    ], JSON_UNESCAPED_UNICODE);
    
} catch (Exception $e) {
    // 记录错误
    logMessage("Exception: " . $e->getMessage());
    
    // 返回错误响应
    http_response_code(400);
    echo json_encode([
        'success' => false,
        'message' => $e->getMessage()
    ], JSON_UNESCAPED_UNICODE);
} catch (Error $e) {
    // 记录致命错误
    logMessage("Fatal error: " . $e->getMessage());
    
    // 返回错误响应
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => '服务器内部错误: ' . $e->getMessage()
    ], JSON_UNESCAPED_UNICODE);
}
?>